package com.market.plus.core.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.TableGenerator;

@Entity
@Table(name = "NEWS")
@NamedQueries( { 
   @NamedQuery(name = News.FIND_ALL, query = "SELECT news FROM News news"),
   @NamedQuery(name = News.FIND_BY_PARTICIPANTID, query = "SELECT news FROM News news where news.participant.id=:participantId and news.newsType=:newsType and news.status=:status"),
   @NamedQuery(name = News.FIND_BY_PARTICIPANT_GUIDS, query = "SELECT news FROM News news where news.participant.id=:participantId and news.guid in (:guids) and news.newsType=:newsType and news.status=:status"),
   @NamedQuery(name = News.FIND_BY_GUIDS, query = "SELECT news FROM News news where news.guid in (:guids) and news.newsType=:newsType and news.status=:status"),
   @NamedQuery(name = News.FIND_BY_PARTICIPANT_GUID, query = "SELECT news FROM News news where news.guid=:guids and news.status=:status")})
public class News implements Persistable, ModifyedInfo, StatusInfo {

   public static final String FIND_ALL = "NEWS.FIND_ALL";

   public static final String FIND_BY_PARTICIPANTID = "NEWS.FIND_BY_PARTICIPANTID";

   public static final String FIND_BY_PARTICIPANT_GUIDS = "NEWS.FIND_BY_PARTICIPANT_GUIDS";

   public static final String FIND_BY_GUIDS = "NEWS.FIND_BY_GUIDS";

   public static final String FIND_BY_PARTICIPANT_GUID = "NEWS.FIND_BY_PARTICIPANT_GUID";

   public static final String PARA_PARTICIPANTID = "participantId";

   public static final String PARA_NEWSTYPE = "newsType";

   public static final String PARA_STATUS = "status";

   public static final String PARA_GUIDS = "guids";

   @Id
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "GEN_NEWS")
   @TableGenerator(name = "GEN_NEWS", table = "SEQUENCE_LIST", allocationSize = 1, initialValue = 1, pkColumnName = "NAME", valueColumnName = "NEXT_SEQUENCE", pkColumnValue = "NEWS")
   @Column(name = "NEWS_ID")
   private Long id;

   @Column(name = "Title", nullable = false)
   private String title;

   @Column(name = "CONTENT")
   private String content;

   @Column(name = "GUID")
   private String guid;

   @Column(name = "CREATED_USER")
   private String createdUser;

   @Column(name = "CREATED_DATE")
   private Date createdDate;

   @Column(name = "MODIFYED_USER")
   private String modifyedUser;

   @Column(name = "MODIFYED_DATE")
   private Date modifyedDate;

   @Column(name = "NEWSTYPE")
   @Enumerated(EnumType.ORDINAL)
   private NewsType newsType;

   @Column(name = "STATUS")
   @Enumerated(EnumType.ORDINAL)
   private Status status;

   @Column(name = "TOTALCOMMENTS")
   private Integer totalComments;

   @Column(name = "HASPUBLIC")
   private Boolean hasPublic;

   @ManyToOne
   @JoinColumn(name = "PARTICIPANT_ID")
   private Participant participant;

   @OrderBy("modifyedDate ASC")
   @OneToMany(cascade=CascadeType.ALL, mappedBy="news", orphanRemoval=true)
   private Set<Comment> comments;

   @OneToMany(cascade=CascadeType.ALL, mappedBy="news", orphanRemoval=true, fetch=FetchType.LAZY)
   private Set<NewsFriends> newsFriends;
   
   @ManyToMany
   @JoinTable(name = "NEWS_FILE", joinColumns = @JoinColumn(name = "NEWS_FILE_ID", referencedColumnName = "NEWS_ID"), 
         inverseJoinColumns = @JoinColumn(name = "FILE_NEWS_ID", referencedColumnName = "CONTENTFILE_ID"))
   private Set<ContentFile> contentFiles;

   public News() {
      contentFiles = new HashSet<ContentFile>();
      comments = new HashSet<Comment>();
      newsFriends = new HashSet<NewsFriends>();
   }

   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public Status getStatus() {
      return status;
   }

   public void setStatus(Status status) {
      this.status = status;
   }

   public String getCreatedUser() {
      return createdUser;
   }

   public void setCreatedUser(String createdUser) {
      this.createdUser = createdUser;
   }

   public Date getCreatedDate() {
      return createdDate;
   }

   public void setCreatedDate(Date createdDate) {
      this.createdDate = createdDate;
   }

   public String getModifyedUser() {
      return modifyedUser;
   }

   public void setModifyedUser(String modifyedUser) {
      this.modifyedUser = modifyedUser;
   }

   public Date getModifyedDate() {
      return modifyedDate;
   }

   public void setModifyedDate(Date modifyedDate) {
      this.modifyedDate = modifyedDate;
   }

   public String getTitle() {
      return title;
   }

   public void setTitle(String title) {
      this.title = title;
   }

   public String getContent() {
      return content;
   }

   public void setContent(String content) {
      this.content = content;
   }

   public NewsType getNewsType() {
      return newsType;
   }

   public void setNewsType(NewsType newsType) {
      this.newsType = newsType;
   }

   public List<ContentFile> getContentFiles() {
      return new ArrayList<ContentFile>(this.contentFiles);
   }

   public void setContentFiles(List<ContentFile> contentFiles) {
      this.contentFiles.clear();
      this.contentFiles.addAll(contentFiles);
   }

   public Participant getParticipant() {
      return participant;
   }

   public void setParticipant(Participant participant) {
      this.participant = participant;
   }

   public String getGuid() {
      return guid;
   }

   public void setGuid(String guid) {
      this.guid = guid;
   }

   public List<Comment> getComments() {
      List<Comment> listComments = new ArrayList<Comment>();
      int index = 0;
      for (Iterator<Comment> it = this.comments.iterator(); it.hasNext();){
         listComments.add(index++, it.next());
      }
      return listComments;
   }

   public int getCommentSize(){
      return this.comments.size();
   }
   /*public void setComments(List<Comment> comments) {
      this.comments.clear();
      this.comments.addAll(comments);
   }*/

   public void addComment(Comment comment){
      comment.setNews(this);
      comments.add(comment);
   }

   public void removeOlderComment(){
      if (comments.size() > 0){
         comments.remove(comments.iterator().next());
      }
   }
   
   public Set<NewsFriends> getNewsFriends() {
      return newsFriends;
   }

   public void setNewsFriends(Set<NewsFriends> newsFriends) {
      this.newsFriends = newsFriends;
   }

   public void clearComments(){
      this.comments.clear();
   }

   public Integer getTotalComments() {
      return totalComments;
   }

   public void setTotalComments(Integer totalComments) {
      this.totalComments = totalComments;
   }

   public void addContentFile(ContentFile contentFile){
      this.contentFiles.add(contentFile);
   }

   public Boolean getHasPublic() {
      return hasPublic;
   }

   public void setHasPublic(Boolean hasPublic) {
      this.hasPublic = hasPublic;
   }

   public NewsFriends createNewsFriendsInts(){
      NewsFriends newsFriends = new NewsFriends();
      newsFriends.setNews(this);
      return newsFriends;
   }

   @Override
   public boolean equals(Object obj) {
      News propertyCompare = (News) obj;
      if (this.getId().longValue() == propertyCompare.getId().longValue()) {
         return true;
      }
      return false;
   }
}
